﻿using Microsoft.EntityFrameworkCore;
using ZH.GPT.Domains.User.Response;
using ZH.GPT.Extend;
using ZH.GPT.Infrastructures.Entities;
using ZH.GPT.Infrastructures.Enum;
using ZH.GPT.Infrastructures.Extension;
using ZH.GPT.Infrastructures.Repositories.Interface;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Z.EntityFramework.Plus;

namespace ZH.GPT.Infrastructures.Repositories
{
    /// <summary>
    /// 用户Service 
    /// </summary>
    public class UserRepository : BaseRepository, IUserRepository
    {
        /// <summary>
        /// 用户Service构造函数
        /// </summary>
        /// <param name="dbContextFactory"></param>
        public UserRepository(IDbContextFactory dbContextFactory) : base(dbContextFactory)
        {

        }

        /// <summary>
        /// 获取用户名称
        /// </summary>
        /// <param name="id">id</param>
        /// <param name="dbOption">主从库</param>
        /// <returns></returns>
        public async Task<UserPDTO> GetUserAsync(Guid id, DBOption dbOption = DBOption.Slave)
        {
            User user = await this.FindAsync<User>(id, dbOption);
            UserPDTO userDTO = null;
            if (user != null)
                userDTO = new UserPDTO
                {
                    Id = user.Id.ToString(),
                    Account = user.Account,
                    Name = user.Name,
                    //IsAdmin = user.IsAdmin,
                    //IsSuperAdmin = user.IsSuperAdmin,
                    //IsActive = user.IsActive,
                    //TenantId = user.TenantId,
                    Created = user.CreatedTime,
                    Modified = user.ModifiedTime,
                    //DepartmentId = user.DepartmentId,
                };
            return userDTO;
        }

        /// <summary>
        /// 批量新增
        /// </summary>
        /// <returns></returns>
        public async Task<int> AddUserBatchTestAsync()
        {
            {
                Stopwatch watch = Stopwatch.StartNew();
                List<User> users = new List<User>();
                for (int i = 0; i < 10000; i++)
                {
                    User user = new User
                    {
                        Id = new Guid().ToString(),
                        Account = i.ToString(),
                        Password = "123",
                        Name = $"test{i}",
                        //IsActive = 1,
                        //Created = DateTime.Now,
                    };
                    users.Add(user);
                }
                int count = await AddBatchAsync<User>(users);
                watch.Stop();
            }

            //sql，如此批量操作时不要使用sql每一条执行
            //{
            //    Stopwatch watch = Stopwatch.StartNew();
            //    dbContext = dbContextFactory.GetDbContext(DBOption.Master);
            //    for (int i = 0; i < 100000; i++)
            //    {
            //        string sql = $"insert into users (id,account,password,name,is_admin,is_super_admin,is_active,tenant_id,created,department_id) values ('{Guid.NewGuid().ToString()}','test{i.ToString()}','123','111',1,1,1,'123','{DateTime.Now}','48c9dafe-7a40-4796-a8db-599ae1f1fe99')";
            //        await dbContext.Database.ExecuteSqlRawAsync(sql);
            //    }
            //    watch.Stop();
            //}

            //EF删除
            {
                dbContext = (MainDBContext)dbContextFactory.GetDbContext(DBOption.Master);
                var list = dbContext.Set<User>().Where(u => u.Id != Guid.NewGuid().ToString()).ToList();
                Stopwatch watch = Stopwatch.StartNew();
                foreach (var item in list)
                {
                    dbContext.Entry(item).State = EntityState.Deleted;
                }
                int count = dbContext.SaveChanges();
                watch.Stop();
            }


            //加了Z.EntityFramework.Plus.EFCore的删除，一定使用这个，Z.EntityFramework.Plus.EFCore可以将EF删除的两条sql变成一条执行
            {
                Stopwatch watch = Stopwatch.StartNew();
                int count = dbContext.Set<User>().Where(u => u.Id != Guid.NewGuid().ToString()).Delete();
                //设置块级大小（默认4000）
                //int count = db.Set<TestTwo>().Where(u => u.id != "1").Delete(u => u.BatchSize = 80000);
                watch.Stop();
            }

            //Z.EntityFramework.Plus.EFCore的update
            int updateCount = dbContext.Set<User>().Where(u => u.Id == Guid.NewGuid().ToString()).Update(x => new User()
            {
                Name = "",
            });
            return 0;
        }
    }
}
